#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ford UK NGc2 爬虫Colour模块
专门处理颜色配置的抓取和数据提取，包含滚动抓取机制
"""

import time
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException


class ColourHandler:
    """Colour配置处理器"""
    
    def __init__(self, driver, wait, navigation_handler):
        """
        初始化Colour处理器
        
        Args:
            driver: WebDriver实例
            wait: WebDriverWait实例
            navigation_handler: 导航处理器实例
        """
        self.driver = driver
        self.wait = wait
        self.navigation_handler = navigation_handler
    
    def scrape_colour_data(self):
        """
        抓取Colour页面的数据，实现滚动抓取机制
        
        Returns:
            list: 颜色选项列表
        """
        print("    🌈 开始抓取Colour选项...")
        
        try:
            # 步骤1：导航到Colour页面
            if not self.navigate_to_colour_page():
                print("    ❌ 无法进入Colour页面")
                return []
            
            # 步骤2：等待Colour页面加载
            print("    ⏳ 等待Colour页面加载...")
            time.sleep(3)
            
            # 步骤3：实现滚动抓取频色选项
            colour_options = self.extract_colour_options_with_scrolling()
            
            if colour_options:
                print(f"    ✅ 成功抓取到 {len(colour_options)} 个颜色选项")
                for i, colour in enumerate(colour_options, 1):
                    print(f"      {i}. {colour.get('name', 'Unknown')} - {colour.get('price', 'N/A')}")
            else:
                print("    ⚠️  未找到颜色选项")
                # 使用默认颜色数据
                colour_options = [
                    {"name": "Solid Paint", "price": "Standard", "colour_code": ""},
                    {"name": "Metallic Paint", "price": "+£300", "colour_code": ""}
                ]
            
            return colour_options
            
        except Exception as e:
            print(f"    ❌ 抓取Colour数据时出错: {e}")
            return []
    
    def navigate_to_colour_page(self):
        """
        导航到Colour配置页面
        
        Returns:
            bool: 是否成功进入Colour页面
        """
        print(f"      🧭 导航到Colour页面...")
        
        try:
            # 方法1：查找导航栏中的Colour按钮
            nav_state = self.navigation_handler.get_navigation_state()
            if nav_state and ('Colour' in nav_state or 'Color' in nav_state):
                colour_key = 'Colour' if 'Colour' in nav_state else 'Color'
                colour_nav_info = nav_state[colour_key]
                
                if (colour_nav_info.get('enabled', False) and 
                    not colour_nav_info.get('current', False)):
                    
                    colour_element = colour_nav_info['element']
                    print(f"      ✓ 找到Colour导航按钮")
                    
                    self.driver.execute_script("arguments[0].click();", colour_element)
                    time.sleep(2)
                    
                    if self.verify_colour_page_loaded():
                        print("      ✅ 通过导航栏进入Colour页面")
                        return True
            
            # 方法2：直接查找Colour相关链接
            colour_selectors = [
                'a[href*="colour"]',
                'a[href*="color"]',
                'button[data-testid*="colour"]',
                '[class*="colour"] a',
                'nav a:contains("Colour")',
                'nav a:contains("Color")'
            ]
            
            for selector in colour_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    for element in elements:
                        if element.is_displayed() and element.is_enabled():
                            print(f"      ✓ 找到Colour链接: {selector}")
                            element.click()
                            time.sleep(2)
                            
                            if self.verify_colour_page_loaded():
                                print("      ✅ 通过直接链接进入Colour页面")
                                return True
                except Exception:
                    continue
            
            # 方法3：检查当前URL是否已经在Colour页面
            current_url = self.driver.current_url.lower()
            if 'colour' in current_url or 'color' in current_url:
                print("      ✓ 当前URL显示已在Colour页面")
                return self.verify_colour_page_loaded()
            
            print("      ❌ 所有Colour导航方法都失败")
            return False
            
        except Exception as e:
            print(f"      ❌ 导航到Colour页面时出错: {e}")
            return False
    
    def verify_colour_page_loaded(self):
        """
        验证Colour页面是否已加载
        
        Returns:
            bool: 是否已加载Colour页面
        """
        try:
            # 检查方法1：查找Colour相关的页面元素
            colour_indicators = [
                'div[class*="simplebar-content"][style*="padding: 0px"]',  # 用户澄清的业务逻辑
                'div[role="radio"][class*="ColoursSection__ColourItemWrapper"]',  # 用户澄清的颜色选项
                'div[data-testid*="colour"]',
                '[class*="colour-option"]',
                'button[class*="ColourOption"]',
                '[class*="ProductTile"][class*="Colour"]'
            ]
            
            for selector in colour_indicators:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        print(f"        ✓ Colour页面验证成功: 找到 {len(elements)} 个Colour元素")
                        return True
                except Exception:
                    continue
            
            # 检查方法2：页面标题或URL
            current_url = self.driver.current_url.lower()
            page_title = self.driver.title.lower()
            
            if 'colour' in current_url or 'color' in current_url or 'colour' in page_title:
                print("        ✓ Colour页面验证成功: URL或标题包含colour")
                return True
            
            # 检查方法3：导航状态
            nav_state = self.navigation_handler.get_navigation_state()
            colour_keys = ['Colour', 'Color']
            for colour_key in colour_keys:
                if colour_key in nav_state:
                    if nav_state[colour_key].get('current', False):
                        print("        ✓ Colour页面验证成功: 导航状态显示当前在Colour页面")
                        return True
            
            print("        ❌ Colour页面验证失败")
            return False
            
        except Exception as e:
            print(f"        ❌ 验证Colour页面时出错: {e}")
            return False
    
    def extract_colour_options_with_scrolling(self):
        """
        通过滚动机制提取所有颜色选项
        
        Returns:
            list: 颜色选项列表
        """
        print("      📜 开始滚动抓取颜色选项...")
        
        try:
            all_colour_options = []
            
            # 步骤1：检测颜色容器
            colour_container = self.detect_colour_container()
            if not colour_container:
                print("      ❌ 未找到颜色容器")
                return []
            
            # 步骤2：提取初始可见的颜色选项
            initial_colours = self.extract_visible_colour_options(colour_container)
            all_colour_options.extend(initial_colours)
            
            print(f"      ✓ 初始提取到 {len(initial_colours)} 个颜色")
            
            # 步骤3：通过滚动获取更多颜色
            additional_colours = self.scroll_and_extract_more_colours(colour_container, initial_colours)
            all_colour_options.extend(additional_colours)
            
            if additional_colours:
                print(f"      ✓ 滚动获取到 {len(additional_colours)} 个额外颜色")
            
            # 步骤4：去重
            unique_colours = self.deduplicate_colour_options(all_colour_options)
            
            print(f"      📊 总共获得 {len(unique_colours)} 个唯一颜色选项")
            return unique_colours
            
        except Exception as e:
            print(f"      ❌ 滚动抓取颜色选项时出错: {e}")
            return []
    
    def detect_colour_container(self):
        """
        检测颜色选项的容器元素
        根据用户澄清：只有在 simplebar-content 容器里的条目才是颜色
        
        Returns:
            WebElement or None: 颜色容器元素
        """
        try:
            # 根据用户澄清的业务逻辑
            container_selector = 'div.simplebar-content[style*="padding: 0px"]'
            
            containers = self.driver.find_elements(By.CSS_SELECTOR, container_selector)
            
            for container in containers:
                if container.is_displayed():
                    # 检查容器内是否包含颜色选项
                    colour_items = container.find_elements(
                        By.CSS_SELECTOR, 
                        'div[role="radio"][class*="ColoursSection__ColourItemWrapper"]'
                    )
                    
                    if colour_items:
                        print(f"        ✓ 找到颜色容器，包含 {len(colour_items)} 个初始颜色项")
                        return container
            
            print("        ⚠️  未找到符合条件的颜色容器")
            return None
            
        except Exception as e:
            print(f"        检测颜色容器时出错: {e}")
            return None
    
    def extract_visible_colour_options(self, container):
        """
        从容器中提取当前可见的颜色选项
        
        Args:
            container (WebElement): 颜色容器
            
        Returns:
            list: 当前可见的颜色选项
        """
        colour_options = []
        
        try:
            # 根据用户澄清的业务逻辑：每个颜色在ColoursSection__ColourItemWrapper标签里
            colour_selector = 'div[role="radio"][class*="ColoursSection__ColourItemWrapper"]'
            
            elements = container.find_elements(By.CSS_SELECTOR, colour_selector)
            print(f"        找到 {len(elements)} 个颜色选项元素")
            
            for element in elements:
                if element.is_displayed():
                    colour_data = self.extract_colour_option_data(element)
                    if colour_data:
                        colour_options.append(colour_data)
                        print(f"          ✓ 提取颜色: {colour_data['name']} - {colour_data['price']}")
        
        except Exception as e:
            print(f"        提取颜色选项时出错: {e}")
        
        return colour_options
    
    def scroll_and_extract_more_colours(self, container, initial_colours):
        """
        通过滚动显示更多颜色选项
        
        Args:
            container (WebElement): 颜色容器
            initial_colours (list): 初始可见的颜色选项
            
        Returns:
            list: 通过滚动获取的颜色选项
        """
        print("      📜 开始滚动显示更多颜色...")
        
        additional_colours = []
        
        try:
            # 获取初始颜色名称集合
            initial_names = set(colour.get('name', '') for colour in initial_colours)
            
            # 定义滚动参数
            scroll_attempts = 5
            scroll_distance = 300
            
            for i in range(scroll_attempts):
                print(f"        🔽 第 {i+1} 次滚动...")
                
                # 向下滚动
                self.driver.execute_script(f"""
                    arguments[0].scrollBy(0, {scroll_distance});
                """, container)
                
                time.sleep(1)  # 等待滚动动画完成
                
                # 抓取新显示的颜色选项
                new_colours = self.extract_visible_colour_options(container)
                
                # 检查是否有新颜色
                found_new = False
                for colour in new_colours:
                    colour_name = colour.get('name', '')
                    if colour_name and colour_name not in initial_names:
                        additional_colours.append(colour)
                        initial_names.add(colour_name)
                        found_new = True
                        print(f"          ✓ 发现新颜色: {colour_name}")
                
                if not found_new:
                    print(f"        📍 第 {i+1} 次滚动未发现新颜色，可能已到底部")
                    
                    # 尝试反向滚动
                    if i < scroll_attempts - 1:  # 不在最后一次尝试反向
                        print(f"        🔼 尝试反向滚动...")
                        self.driver.execute_script(f"""
                            arguments[0].scrollBy(0, -{scroll_distance//2});
                        """, container)
                        time.sleep(1)
                    else:
                        break
            
            return additional_colours
            
        except Exception as e:
            print(f"        滚动获取颜色时出错: {e}")
            return []
    
    def extract_colour_option_data(self, element):
        """
        从颜色选项元素中提取数据
        根据用户澄清：从 aria-label="Race Red £0" 解析颜色名称和价格
        
        Args:
            element (WebElement): 颜色选项元素
            
        Returns:
            dict or None: 颜色选项数据
        """
        try:
            name = ''
            price = ''
            colour_code = ''
            
            # 根据用户澄清的业务逻辑：从aria-label解析
            aria_label = element.get_attribute('aria-label')
            
            if aria_label:
                # 解析aria-label，格式如："Race Red £0"
                if '£' in aria_label:
                    parts = aria_label.split('£')
                    name = parts[0].strip()  # £符号前是颜色名称
                    price = '£' + parts[1].strip()  # £符号后是价格
                else:
                    name = aria_label.strip()
                    price = 'Standard'
            
            # 尝试获取data-item-code作为颜色代码
            colour_code = element.get_attribute('data-item-code') or ''
            
            # 如果aria-label没有获取到名称，尝试其他方法
            if not name:
                name_selectors = [
                    '[class*="title"]',
                    '[class*="name"]',
                    'span, div, p'
                ]
                
                for name_selector in name_selectors:
                    try:
                        name_element = element.find_element(By.CSS_SELECTOR, name_selector)
                        name_text = name_element.text.strip()
                        if name_text and '£' not in name_text:
                            name = name_text
                            break
                    except Exception:
                        continue
            
            # 如果还没有价格，尝试查找价格元素
            if not price or price == 'Standard':
                price_selectors = [
                    'span:contains("£")',
                    '[class*="price"]',
                    '*[text()[contains(., "£")]]'
                ]
                
                for price_selector in price_selectors:
                    try:
                        price_elements = element.find_elements(By.CSS_SELECTOR, price_selector)
                        for price_elem in price_elements:
                            price_text = price_elem.text.strip()
                            if '£' in price_text:
                                price = price_text
                                break
                        if price and '£' in price:
                            break
                    except Exception:
                        continue
            
            # 确保有默认价格
            if not price:
                price = 'Standard'
            
            if name:
                return {
                    'name': name,
                    'price': price,
                    'colour_code': colour_code,
                    'element': element
                }
            
            return None
            
        except Exception as e:
            print(f"          提取颜色选项数据时出错: {e}")
            return None
    
    def deduplicate_colour_options(self, colour_options):
        """
        去除重复的颜色选项
        
        Args:
            colour_options (list): 原始颜色选项列表
            
        Returns:
            list: 去重后的颜色选项列表
        """
        try:
            seen_names = set()
            unique_colours = []
            
            for colour in colour_options:
                colour_name = colour.get('name', '')
                if colour_name and colour_name not in seen_names:
                    seen_names.add(colour_name)
                    unique_colours.append(colour)
            
            return unique_colours
            
        except Exception as e:
            print(f"        去重颜色选项时出错: {e}")
            return colour_options  # 返回原始列表作为备用
    
    def update_car_objects_with_colour_data(self, car_series, target_model, colour_data):
        """
        使用Colour数据更新CarObject实例
        
        Args:
            car_series (CarSeries): 车系对象
            target_model (str): 目标车型名称
            colour_data (list): 颜色数据列表
        """
        print(f"    🔄 为 {target_model} 的CarObject添加Colour数据...")
        
        try:
            updated_objects = 0
            
            # 转换颜色数据为字符串列表（保持向后兼容）
            colour_names = []
            for colour in colour_data:
                colour_name = colour.get('name', '')
                colour_price = colour.get('price', 'Standard')
                
                # 格式：颜色名 (价格)
                if colour_price and colour_price != 'Standard':
                    colour_display = f"{colour_name} ({colour_price})"
                else:
                    colour_display = colour_name
                
                if colour_display:
                    colour_names.append(colour_display)
            
            # 遍历所有CarObject，找到匹配的车型
            for car_object in car_series.car_object_list:
                if car_object.model_name.lower() == target_model.lower():
                    # 替换原有的颜色数据
                    car_object.colors = colour_names.copy()
                    updated_objects += 1
                    
                    print(f"      ✓ 为 {target_model} + {car_object.drive} 添加 {len(colour_names)} 个颜色选项")
            
            print(f"    ✅ 共更新了 {updated_objects} 个CarObject，添加了 {len(colour_names)} 个颜色选项")
            
        except Exception as e:
            print(f"    ❌ 更新CarObject时出错: {e}")